// ES5 实现类和继承

// 流行的面向对象编写方式：构造函数 + 原型的混合方式来模拟一个类。

// 一、定义类

// 1、通过构造函数添加属性
function Person(name, age) {
    this.name = name; // 前面的name表示的是属性名，后面的name表示的是参数
    this.age = age;
}

// 2、通过原型添加方法
Person.prototype.say = function() {
    return "我叫" + this.name + "，我今年" + this.age + "岁。";
}

// 实例化：通过Person类创建具体的一个人的对象，比如张三这个人
let zhangsan = new Person("张三", 18);
console.log(zhangsan.say());

// 实例化：通过Person类创建具体的一个人的对象，比如李四这个人
let lisi = new Person("李四", 28);
console.log(lisi.say());

// 二、继承

// 1、继承构造函数
function Student(name, age, school) {
    // 继承父类所有的属性
    Person.call(this, name, age); // 让父类内部的this指向子类的对象
    // 子类可以拥有自己的属性，比如 school
    this.school = school;
}

// 2、继承原型

// 直接将父类的原型赋值给子类的原型不可以这样做！
// 因为 prototype 本质是一个对象，这样赋值是引用传值，这样子类会影响父类。这不是继承！
// Student.prototype = Person.prototype;

// 通过for in 遍历 Person.prototype 的方式来完成子类继承父类的原型
for(let key in Person.prototype) {
    Student.prototype[key] = Person.prototype[key];
}

// 子类也可以拥有自己的方法
Student.prototype.study = function() {
    return this.name + "正在" + this.school + "上学。";
}

let luoyue = new Student("罗月", 18, "家里蹲大学");
console.log(luoyue.say());
console.log(luoyue.study());
